package com.smasher.zxing.activity;

import android.app.Activity;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Vibrator;
import android.util.Log;

import com.smasher.zxing.R;

import java.io.IOException;


/**
 * 音效及震动管理器
 * 职责：管理二维码扫描成功后的提示音效和震动反馈
 */
public class ScanFeedbackDelegate {

    private static final float BEEP_VOLUME = 0.10f;
    private static final long VIBRATE_DURATION = 200L;
    public static final String TAG = "ScanFeedbackDelegate";

    private final AudioManager audioService;
    private final Vibrator vibrator;

    private MediaPlayer mediaPlayer;
    private boolean vibrate;
    private boolean playBeep;

    public ScanFeedbackDelegate(Activity context) {
        audioService = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
        initMediaPlayer();
        context.setVolumeControlStream(AudioManager.STREAM_MUSIC);
        initBeepSound(context);
    }

    /**
     * 初始化媒体播放器
     * 配置：
     * 1. 设置音频流类型为媒体音乐
     * 2. 添加播放完成监听器（用于循环播放）
     */
    private void initMediaPlayer() {
        if (mediaPlayer == null) {
            mediaPlayer = new MediaPlayer();
            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            mediaPlayer.setOnCompletionListener(beepListener);
        }
    }

    /**
     * 加载提示音资源
     *
     * @param context 上下文对象，用于访问资源
     *                说明：
     *                1. 从raw资源加载beep音效
     *                2. 设置双声道音量
     *                3. 异常时清空mediaPlayer引用
     */
    private void initBeepSound(Context context) {
        if (playBeep && mediaPlayer != null) {
            try {
                AssetFileDescriptor file = context.getResources().openRawResourceFd(R.raw.beep);
                mediaPlayer.setDataSource(file.getFileDescriptor(),
                        file.getStartOffset(), file.getLength());
                file.close();
                mediaPlayer.setVolume(BEEP_VOLUME, BEEP_VOLUME);
                mediaPlayer.prepare();
            } catch (IOException e) {
                mediaPlayer = null;
            }
        }
    }

    /**
     * 检查当前铃声模式
     * 逻辑：当处于静音或震动模式时禁用提示音
     */
    private void checkRingerMode() {
        if (audioService.getRingerMode() != AudioManager.RINGER_MODE_NORMAL) {
            playBeep = false;
        }
    }

    /**
     * 执行音效震动组合操作
     * 流程：
     * 1. 检查当前铃声模式
     * 2. 播放提示音（如果启用）
     * 3. 触发震动（如果启用）
     * 注意：需处理MediaPlayer的非法状态异常
     */
    public void playBeepSoundAndVibrate() {
        checkRingerMode();

        if (playBeep && mediaPlayer != null) {
            try {
                mediaPlayer.start();
            } catch (IllegalStateException e) {
                Log.e(TAG, "MediaPlayer not initialized", e);
                // 重新初始化或降级处理
            }
        }
        if (vibrate) {
            if (vibrator != null) {
                vibrator.vibrate(VIBRATE_DURATION);
            }
        }
    }
    // region 属性访问器

    /**
     * @return 是否启用震动反馈
     */
    public boolean isVibrate() {
        return vibrate;
    }

    /**
     * @param vibrate 设置震动反馈开关
     */
    public void setVibrate(boolean vibrate) {
        this.vibrate = vibrate;
    }

    /**
     * @return 是否启用提示音
     */
    public boolean isPlayBeep() {
        return playBeep;
    }

    /**
     * @param playBeep 设置提示音开关
     */
    public void setPlayBeep(boolean playBeep) {
        this.playBeep = playBeep;
    }
    // endregion
    /**
     * 播放完成监听器
     * 功能：播放完成后自动重置到起始位置
     */
    private final MediaPlayer.OnCompletionListener beepListener =
            mediaPlayer -> mediaPlayer.seekTo(0);

    /**
     * 释放媒体资源
     * 说明：在宿主生命周期结束时必须调用，防止内存泄漏
     */
    public void release() {
        if (mediaPlayer != null) {
            mediaPlayer.release();
            mediaPlayer = null;
        }
    }

}
